#include "Polygon.h"

namespace ftb
{

	Polygon::Polygon(const std::vector<vec2f>& points, const std::string& texturepath)
		: m_TexturePath(texturepath)
	{
		for(std::vector<vec2f>::const_iterator it = points.begin();
			it != points.end();
			++it)
		{
			m_Points.push_back(*it);
		}
	}

	Polygon::Polygon(const vec2f& a, const vec2f& b, const vec2f& c)
	{
		m_Points.push_back(a);
		m_Points.push_back(b);
		m_Points.push_back(c);
	}

	void Polygon::Add(const vec2f& v)
	{
		m_Points.push_back(v);
	}

	void Polygon::Split(unsigned int index)
	{
		vec2f a = m_Points[index], b;
		unsigned int insert_index = 0;
		if(index == m_Points.size() - 1) 
		{
			b = m_Points[0];
			insert_index = m_Points.size();
		}
		else
		{
			b = m_Points[index + 1];
			insert_index = index + 1;
		}
	
		vec2f diff = b - a;
		float length = Length(diff) * 0.5f;
		vec2f newv = a + (length * Normalice(diff));
	
		m_Points.insert(m_Points.begin() + insert_index, newv);
	}
	/*
	boolean PointInTriangle(const vec2f& p, const vec2f& a, const vec2f& b, const vec2f& c)
	{
		auto sameside = [](const vec2f& p1, const vec2f& p2, const vec2f& a, const vec2f& b) -> boolean
		{
			auto sgn = [](float f) -> int
			{
				if(f <= 0) 
					return 0;
				else 
					return 1;
			};
			if(sgn(CrossProduct(b - a, p1 - a)) == sgn(CrossProduct(b - a, p2 - a)))
				return true;
			else
				return false;
		};

		if(sameside(p,a, b,c) && sameside(p,b, a,c) && sameside(p,c, a,b))
			return true;
		else 
			return false;
	}
	*/

	// todo: vector = bad
	void Polygon::Render(Renderer& renderObj)
	{
		auto calc_index = [](int index, int size) -> unsigned int
			{
				if(index < 0) return size - 1;
				else if(index > size - 1) return 0;
				else return index;
			};

		std::vector<vec2f> points = m_Points;
		for(int i = points.size() - 1; points.size() >= 3; i--)
		{
			int size = points.size();
			int l = calc_index(i - 1, size), m = i, r = calc_index(i + 1, size);
			vec2f a(points[l]), b(points[m]), c(points[r]);
			vec2f tex(0.0f, 1.0f);

			renderObj.RenderTriangle(a, a,
									  b, b,
									  c, c,
									  m_TexturePath);
			points.erase(points.begin() + m); // erase a
		}
		
	}
}